package com.eriloan.easyPage.plugins.dao.impl;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.log4j.Logger;

import com.eriloan.easyPage.plugins.dao.IDao;
import com.eriloan.easyPage.util.EasyPageContext;

/**
 * 
 * <p>Copyright: All Rights Reserved</p>
 * <p>Company: 北京荣之联科技股份有限公司 http://www.ronglian.com</p>
 * <p>Description: BAE Dao 类 </p>
 * <p>Author:Eric Shi/史丙利</p>
 */
public class BaeDao implements IDao{

	public static final Logger log = Logger.getLogger(BaeDao.class);

	/**
	 * 数据库连接对象
	 */
	private Connection conn;

	/**
	 * SQL查询操作对象
	 */
	private QueryRunner queryRunner;

	private String host;
	private String port;
	private String username;
	private String password;
	private String databaseName;
	private String connUrl;

	/**
	 * 
	 * <br/>Description:构造函数
	 * <p>Author:Eric Shi/史丙利</p>
	 * 
	 * @param dbName
	 */
	public BaeDao(String dbName){
		this.databaseName = dbName;
	}

	/**
	 * 
	 * <br/>Description:初始化BAE Connection参数
	 * <p>Author:Eric Shi/史丙利</p>
	 */
	private void initBaeConnectionConfig() throws SQLException{

		EasyPageContext easyPageContext = new EasyPageContext();
		HttpServletRequest request = easyPageContext.getRequest();

		this.host = request.getHeader("BAE_ENV_ADDR_SQL_IP");
		this.port = request.getHeader("BAE_ENV_ADDR_SQL_PORT");
		this.username = request.getHeader("BAE_ENV_AK");
		this.password = request.getHeader("BAE_ENV_SK");

		connUrl = "jdbc:mysql://" + this.host + ":" + this.port + "/" + databaseName + "?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull";

		this.conn = DriverManager.getConnection(connUrl,username,password);
	}

	/**
	 * 
	 * <br/>Description:初始化QueryRunner
	 * <p>Author:Eric Shi/史丙利</p>
	 */
	private void initQueryRunner(){

		try{
			initBaeConnectionConfig();
		}catch(SQLException e){
			try{
				initBaeConnectionConfig();
			}catch(SQLException ex){
				log.warn("Initialize connection failure.",ex);
			}
		}

		if(null == queryRunner){
			queryRunner = new QueryRunner();
		}
	}

	/**
	 * 
	 * <br/>Description:根据SQL和参数返回对应的对象
	 * <p>Author:Eric Shi/史丙利</p>
	 * 
	 * @param sql
	 * @param params
	 * @param clazz
	 * @return
	 */
	public <T> T findObject(String sql,Object[] params,Class<T> clazz){
		initQueryRunner();

		T t = null;

		try{
			t = queryRunner.query(conn,sql,new BeanHandler<T>(clazz),params);
		}catch(SQLException e){
			log.warn("Find object failure.\nSQL:" + sql,e);
		}finally{
			DbUtils.closeQuietly(conn);
		}

		return t;
	}

	/**
	 * 
	 * <br/>Description:根据SQL返回对应的对象
	 * <p>Author:Eric Shi/史丙利</p>
	 * 
	 * @param sql
	 * @param clazz
	 * @return
	 */
	public <T> T findObject(String sql,Class<T> clazz){
		initQueryRunner();

		T t = null;

		try{
			t = queryRunner.query(conn,sql,new BeanHandler<T>(clazz));
		}catch(SQLException e){
			log.warn("Find object failure.\nSQL:" + sql,e);
		}finally{
			DbUtils.closeQuietly(conn);
		}

		return t;
	}

	/**
	 * 
	 * <br/>Description:根据SQL和参数返回对应的对象集合
	 * <p>Author:Eric Shi/史丙利</p>
	 * 
	 * @param sql
	 * @param params
	 * @param clazz
	 * @return
	 */
	public <T> List<T> findList(String sql,Object[] params,Class<T> clazz){
		initQueryRunner();

		List<T> obj = null;

		try{
			obj = queryRunner.query(conn,sql,new BeanListHandler<T>(clazz),params);
		}catch(SQLException e){
			log.warn("Find list failure.\nSQL:" + sql,e);
		}finally{
			DbUtils.closeQuietly(conn);
		}

		return obj;
	}

	/**
	 * 
	 * <br/>Description:根据SQL返回对应的对象集合
	 * <p>Author:Eric Shi/史丙利</p>
	 * 
	 * @param sql
	 * @param params
	 * @param clazz
	 * @return
	 */
	public <T> List<T> findList(String sql,Class<T> clazz){
		initQueryRunner();

		List<T> obj = null;

		try{
			obj = queryRunner.query(conn,sql,new BeanListHandler<T>(clazz));
		}catch(SQLException e){
			log.warn("Find list failure.\nSQL:" + sql,e);
		}finally{
			DbUtils.closeQuietly(conn);
		}

		return obj;
	}

	/**
	 * 
	 * <br/>Description:根据传入参数更新数据
	 * <p>Author:Eric Shi/史丙利</p>
	 * 
	 * @param sql
	 * @param params
	 * @return
	 */
	public int updateAndDeleteObject(String sql,Object[] params){
		int sum = 0;
		try{
			sum = queryRunner.update(conn,sql,params);
		}catch(SQLException e){
			log.warn("Update and delete object failure.\nSQL:" + sql,e);
		}finally{
			DbUtils.closeQuietly(conn);
		}
		return sum;
	}

	/**
	 * 
	 * <br/>Description:根据传入参数更新数据
	 * <p>Author:Eric Shi/史丙利</p>
	 * 
	 * @param sql
	 * @param params
	 * @return
	 */
	public int updateAndDeleteObject(String sql){
		int sum = 0;
		try{
			sum = queryRunner.update(conn,sql);
		}catch(SQLException e){
			log.warn("Update and delete object failure.\nSQL:" + sql,e);
		}finally{
			DbUtils.closeQuietly(conn);
		}
		return sum;
	}

}
